home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / tools / czesc_2 / kme / kme.mod < prev    next >
Text File  |  1992-05-21  |  60KB  |  2,053 lines

  1. (*---------------------------------------------------------------------------
  2.   :Program.     KME.mod
  3.   :Contents.    Keymap-Editor
  4.   :Author.      Christian Stiens
  5.   :Address.     Heustiege 2, W-4710 Lüdinghausen, Germany
  6.   :Copyright.   Freeware, © 92 by cs-soft, all rights reserved
  7.   :Language.    Oberon
  8.   :Translator.  Amiga Oberon V2.25d (inofficial beta version)
  9.   :History.     V1.0, 01-Jul-91: first release
  10.   :History.     V1.1, 28-Oct-91: message filtering, ...
  11.   :History.     V1.2, 26-Mar-92: 2.0-BusyPointer, ...
  12.   :Support.     Iconify by Steffen Köhler
  13.   :Remark.      Compile:  Oberon -dm KME
  14.   :Remark.      Link:     OLink KME -dm
  15. ---------------------------------------------------------------------------*)
  16.  
  17. MODULE KME;
  18.  
  19.   IMPORT
  20.     c  : Console,
  21.     d  : Dos,
  22.     fs : FileSystem,
  23.     fr : FileReq,
  24.     g  : Graphics,
  25.     e  : Exec,
  26.     km : KeyMap,
  27.     I  : Intuition,
  28.     ie : InputEvent,
  29.          NoGuruRq,
  30.     ol : OberonLib,
  31.     rq : Requests,
  32.     str: Strings,
  33.     sys: SYSTEM;
  34.  
  35.  
  36.   CONST
  37.     ver  = "$VER: kme 1.2 (26.3.92)\n\r";
  38.     kmr  = "KME Request:";
  39.     ok   = " Ok ";
  40.     rtry = "Retry";
  41.     cncl = "Cancel";
  42.     oom  = "Out of memory";
  43.     ooc  = "Out of chip mem";
  44.     cow  = "Can't open window";
  45.     clk  = "Can't load keymap";
  46.     csk  = "Can't save keymap";
  47.     wer  = "Write error, delete corrupt file?";
  48.     fae  = "File already exists";
  49.     ovw  = "Overwrite";
  50.     load = "Map is modified, really load another?";
  51.     quit = "Keymap has been modified, really quit?";
  52.     kme  = "KME Keymap Editor V1.2";
  53.     cprt = "© 1992 by Christian Stiens";
  54.     please = "Yes, please";
  55.     forget = "Oh No!";
  56.  
  57.     strLen = 80;
  58.     numGads = 130;
  59.     keyHeight = 14;
  60.  
  61.     W1 = 24;
  62.     W2 = 30;
  63.     S1 = 10;
  64.     C1 = 28;
  65.     S2 = (S1+6*W1-W2*4) DIV 2;
  66.     X1 = -10;
  67.     X2 = 0;
  68.  
  69.     (* Key.type *)
  70.     white = 0;
  71.     gray  = 1;
  72.     nok   = 2;
  73.  
  74.     (* Gadget ID's *)
  75.     idKey=5;
  76.     idAbout=10;
  77.     idIconify=20;
  78.     idQuit=30;
  79.     idMod=50;
  80.     idLoad=101;
  81.     idSave=102;
  82.     idShift=203;
  83.     idAlt=204;
  84.     idControl=205;
  85.     idDownup=206;
  86.     idDead=207;
  87.     idString=208;
  88.     idNop=209;
  89.     idCapsable=210;
  90.     idRepeatable=211;
  91.     idUndo=112;
  92.     idStr=300;
  93.  
  94.   TYPE
  95.  
  96.     KeyMapPtr  = UNTRACED POINTER TO KeyMap;
  97.  
  98.     KeyMap  = STRUCT
  99.       loKeyMapTypes : UNTRACED POINTER TO ARRAY 64 OF SHORTSET;
  100.       loKeyMap      : UNTRACED POINTER TO ARRAY 64 OF LONGINT;
  101.       loCapsable    : UNTRACED POINTER TO ARRAY  8 OF SHORTSET;
  102.       loRepeatable  : UNTRACED POINTER TO ARRAY  8 OF SHORTSET;
  103.       hiKeyMapTypes : UNTRACED POINTER TO ARRAY 56 OF SHORTSET;
  104.       hiKeyMap      : UNTRACED POINTER TO ARRAY 56 OF LONGINT;
  105.       hiCapsable    : UNTRACED POINTER TO ARRAY  7 OF SHORTSET;
  106.       hiRepeatable  : UNTRACED POINTER TO ARRAY  7 OF SHORTSET;
  107.     END;
  108.  
  109.     String = ARRAY strLen OF CHAR;
  110.     Str4   = ARRAY 4 OF CHAR;
  111.  
  112.     Key = STRUCT
  113.       type  : SHORTINT;
  114.       width : INTEGER;
  115.       name  : Str4;
  116.       code  : SHORTINT;
  117.     END;
  118.  
  119.     StrDeskr = ARRAY 8 OF STRUCT
  120.       len,offs: SHORTINT;
  121.     END;
  122.  
  123.     StrDeskrPtr = UNTRACED POINTER TO StrDeskr;
  124.  
  125.     DeadDeskr = ARRAY 8 OF STRUCT
  126.       type,val: SHORTINT;
  127.     END;
  128.  
  129.     DeadDeskrPtr = UNTRACED POINTER TO DeadDeskr;
  130.  
  131.  
  132.   VAR
  133.     attr        : g.TextAttr;
  134.     nw          : I.NewWindow;
  135.     win         : I.WindowPtr;
  136.     scr         : I.ScreenPtr;
  137.     rp          : g.RastPortPtr;
  138.     mes         : I.IntuiMessage;
  139.     Y1          : INTEGER;
  140.     font        : g.TextFontPtr;
  141.     msg         : I.IntuiMessagePtr;
  142.     keyMap      : KeyMapPtr;
  143.     gadCnt      : INTEGER;
  144.     strCnt      : INTEGER;
  145.     gad         : ARRAY numGads OF I.Gadget;
  146.     ioreq       : e.IOStdReq;
  147.     buffer      : ARRAY 8 OF String;
  148.     undobf      : ARRAY 8 OF String;
  149.     strInf      : ARRAY 8 OF I.StringInfo;
  150.     pat         : ARRAY 2 OF INTEGER;
  151.     clickedGad  : I.GadgetPtr;
  152.     gadget      : I.GadgetPtr;
  153.     gadID,i     : INTEGER;
  154.     con         : BOOLEAN;
  155.     lastKeyGad  : I.GadgetPtr;
  156.     kmeIcon     : I.Image;
  157.     kmeIconData : UNTRACED POINTER TO ARRAY 494 OF INTEGER;
  158.     iconX,iconY : INTEGER;
  159.     kmePic      : I.Image;
  160.     kmePicData  : UNTRACED POINTER TO ARRAY 132 OF INTEGER;
  161.     type        : SHORTSET;
  162.     rawCode     : INTEGER;
  163.     oldCode     : INTEGER;
  164.     keyModified : BOOLEAN;
  165.     mapModified : BOOLEAN;
  166.     makeGads    : BOOLEAN;
  167.     fileName    : String;
  168.     seg,newSeg  : e.BPTR;
  169.     string      : String;
  170.     zz          : UNTRACED POINTER TO ARRAY (16+2)*2 OF INTEGER;
  171.     dfltKeyMap  : KeyMap;
  172.     loTypes     : ARRAY 64 OF SHORTSET;
  173.     hiTypes     : ARRAY 56 OF SHORTSET;
  174.     loCaps      : ARRAY 8 OF SHORTSET;
  175.     hiCaps      : ARRAY 7 OF SHORTSET;
  176.     loRepeat    : ARRAY 8 OF SHORTSET;
  177.     hiRepeat    : ARRAY 7 OF SHORTSET;
  178.     loMap       : ARRAY 64 OF LONGINT;
  179.     hiMap       : ARRAY 56 OF LONGINT;
  180.     deadLen     : INTEGER;
  181.     reloTab     : ARRAY 130 OF LONGINT;
  182.     reloTabPtr  : INTEGER;
  183.     chipBuf     : UNTRACED POINTER TO ARRAY 128 OF BYTE;
  184.     dummy       : LONGINT;
  185.  
  186.  
  187.   TYPE
  188.     KeyRow0 = ARRAY 13 OF Key;
  189.     KeyRow1 = ARRAY 23 OF Key;
  190.     KeyRow2 = ARRAY 19 OF Key;
  191.     KeyRow3 = ARRAY 21 OF Key;
  192.     KeyRow4 = ARRAY 22 OF Key;
  193.     KeyRow5 = ARRAY  9 OF Key;
  194.  
  195.   CONST
  196.     keyRow0 = KeyRow0(
  197.       1,W1,"Esc",69,
  198.       nok,S1,"",0,
  199.       1,W2,"f1",80,
  200.       1,W2,"f2",81,
  201.       1,W2,"f3",82,
  202.       1,W2,"f4",83,
  203.       1,W2,"f5",84,
  204.       nok,S1,"",0,
  205.       1,W2,"f6",85,
  206.       1,W2,"f7",86,
  207.       1,W2,"f8",87,
  208.       1,W2,"f9",88,
  209.       1,W2,"f0",89);
  210.  
  211.     keyRow1 = KeyRow1(
  212.       1,W1+S1,"x",0,
  213.       0,W1,"x",1,
  214.       0,W1,"x",2,
  215.       0,W1,"x",3,
  216.       0,W1,"x",4,
  217.       0,W1,"x",5,
  218.       0,W1,"x",6,
  219.       0,W1,"x",7,
  220.       0,W1,"x",8,
  221.       0,W1,"x",9,
  222.       0,W1,"x",10,
  223.       0,W1,"x",11,
  224.       0,W1,"x",12,
  225.       0,W1,"x",13,
  226.       1,W1,"Bs",65,
  227.       nok,S1,"",0,
  228.       1,W1*3 DIV 2,"Del",70,
  229.       1,W1*3 DIV 2,"Help",95,
  230.       nok,S1,"",0,
  231.       1,W1,"x",90,
  232.       1,W1,"x",91,
  233.       1,W1,"x",92,
  234.       1,W1,"x",93);
  235.  
  236.     keyRow2 = KeyRow2(
  237.       1,W1+S1+W1 DIV 2,"Tab",66,
  238.       0,W1,"x",16,
  239.       0,W1,"x",17,
  240.       0,W1,"x",18,
  241.       0,W1,"x",19,
  242.       0,W1,"x",20,
  243.       0,W1,"x",21,
  244.       0,W1,"x",22,
  245.       0,W1,"x",23,
  246.       0,W1,"x",24,
  247.       0,W1,"x",25,
  248.       0,W1,"x",26,
  249.       0,W1,"x",27,
  250.       1,W1*3 DIV 2,"Rtrn",68,
  251.       nok,S1+W1*3+S1,"",0,
  252.       0,W1,"x",61,
  253.       0,W1,"x",62,
  254.       0,W1,"x",63,
  255.       1,W1,"x",74);
  256.  
  257.     keyRow3 = KeyRow3(
  258.       1,C1,"Ctrl",99,
  259.       1,W1,"Caps",98,
  260.       0,W1,"x",32,
  261.       0,W1,"x",33,
  262.       0,W1,"x",34,
  263.       0,W1,"x",35,
  264.       0,W1,"x",36,
  265.       0,W1,"x",37,
  266.       0,W1,"x",38,
  267.       0,W1,"x",39,
  268.       0,W1,"x",40,
  269.       0,W1,"x",41,
  270.       0,W1,"x",42,
  271.       0,W1,"x",43,
  272.       nok,S1+W1*2-C1+S1+W1,"",0,
  273.       0,W1,"Up",76,
  274.       nok,W1+S1,"",0,
  275.       0,W1,"x",45,
  276.       0,W1,"x",46,
  277.       0,W1,"x",47,
  278.       1,W1,"x",94);
  279.  
  280.     keyRow4 = KeyRow4(
  281.       1,C1+W1 DIV 2,"Shft",96,
  282.       0,W1,"x",48,
  283.       0,W1,"x",49,
  284.       0,W1,"x",50,
  285.       0,W1,"x",51,
  286.       0,W1,"x",52,
  287.       0,W1,"x",53,
  288.       0,W1,"x",54,
  289.       0,W1,"x",55,
  290.       0,W1,"x",56,
  291.       0,W1,"x",57,
  292.       0,W1,"x",58,
  293.       1,S1+4*W1-C1-W1 DIV 2,"Shft",97,
  294.       nok,S1,"",0,
  295.       0,W1,"Left",79,
  296.       0,W1,"Down",77,
  297.       0,W1,"Rght",78,
  298.       nok,S1,"",0,
  299.       0,W1,"x",29,
  300.       0,W1,"x",30,
  301.       0,W1,"x",31,
  302.       1,W1,"Entr",67);
  303.  
  304.     keyRow5 = KeyRow5(
  305.       nok,S2,"",0,
  306.       1,W2,"Alt",100,
  307.       1,W2,"LAmi",102,
  308.       0,W1*9,"Spc",64,
  309.       1,W2,"RAmi",103,
  310.       1,W2,"Alt",101,
  311.       nok,S2+S1*2+W1*3,"",0,
  312.       0,W1*2,"x",15,
  313.       0,W1,"x",60);
  314.  
  315. (*---------------------------------------------------------------------*)
  316.  
  317.   TYPE ModData = ARRAY 3,10 OF INTEGER;
  318.  
  319.   CONST
  320.     modData = ModData(
  321.  
  322.       00000U,00000U,
  323.       00000U,00000U,
  324.       00000U,00000U,
  325.       00000U,00000U,
  326.       00000U,00000U,
  327.  
  328.       060C3U,087C0U,
  329.       071CCU,06630U,
  330.       07BCCU,06630U,
  331.       06ECCU,06630U,
  332.       060C3U,087C0U,
  333.  
  334.       0F0F8U,070F0U,
  335.       0CCC0U,0D8CCU,
  336.       0CCF1U,08CCCU,
  337.       0CCC1U,0FCCCU,
  338.       0F0F9U,08CF0U);
  339.  
  340. (*---------------------------------------------------------------------*)
  341.  
  342.   TYPE IntArray5 = ARRAY 5 OF INTEGER;
  343.  
  344.   CONST cycData = IntArray5(
  345.     07800U,
  346.     0CC00U,
  347.     0DE00U,
  348.     0CC00U,
  349.     06000U);
  350.  
  351. (*---------------------------------------------------------------------*)
  352.  
  353.   TYPE IntArray136 = ARRAY 136 OF INTEGER;
  354.  
  355.   CONST Pics16Data = IntArray136(
  356.     00000U, 03800U, 00800U, 03800U, 03800U, 08400U, 03000U, 03000U,
  357.     03000U, 08400U, 0CC00U, 08C00U, 0CC00U, 0CC00U, 0CC00U, 08400U,
  358.     07000U, 0C400U, 01C00U, 00000U, 08400U, 03000U, 0E400U, 03000U,
  359.     08400U, 0C400U, 0A400U, 06400U, 00000U, 0E400U, 00000U, 03C00U,
  360.     00400U, 0F000U, 00400U, 08400U, 03C00U, 00400U, 03000U, 08400U,
  361.     00000U, 0F000U, 0E400U, 0CC00U, 09C00U, 08400U, 03000U, 08400U,
  362.     03000U, 08400U, 08400U, 03000U, 08000U, 0F000U, 08400U, 0CE74U,
  363.     08664U, 03240U, 00264U, 03270U, 08DF8U, 039F8U, 03188U, 03998U,
  364.     08C98U, 00FE0U, 02660U, 024A0U, 02460U, 00E20U, 00FF8U, 03CC0U,
  365.     01998U, 03C98U, 009C0U, 0F3C0U, 0CCC0U, 01E00U, 0CCC0U, 0C0C0U,
  366.     0F080U, 0E080U, 0C880U, 08080U, 03800U, 0F080U, 0E280U, 0CA80U,
  367.     08280U, 03800U, 05FF0U, 00000U, 05FF0U, 0FFA0U, 00000U, 0FFA0U,
  368.     0FF80U, 0FF80U, 0FF80U, 0FF80U, 0FF80U, 0FF80U, 0FF80U, 0F780U,
  369.     0C780U, 00000U, 0C7E0U, 0F7E0U, 00000U, 01000U, 07000U, 00000U,
  370.     0F000U, 00000U, 02000U, 0F000U, 09000U, 00000U, 09000U, 0F000U,
  371.     00000U, 01000U, 08000U, 0F000U, 00000U, 03000U, 03000U, 0FF9FU,
  372.     0FF0FU, 0FF9FU, 08FFFU, 03FFFU, 03C8FU, 03297U, 0888FU, 0FF9FU);
  373.  
  374. (*---------------------------------------------------------------------*)
  375.  
  376.   TYPE IntArray10 = ARRAY 10 OF INTEGER;
  377.  
  378.   CONST Pics32Data = IntArray10(
  379.     027E7U,0C000U,
  380.     02664U,04000U,
  381.     004A4U,08000U,
  382.     02464U,04000U,
  383.     02624U,0C000U);
  384.  
  385. (*---------------------------------------------------------------------*)
  386.  
  387.   TYPE IntArray28 = ARRAY 28 OF INTEGER;
  388.  
  389.   CONST ArrowData = IntArray28(
  390.     03000U, 0FF00U, 03000U, 0CF00U, 00000U, 0CF00U,
  391.     00C00U, 0FF00U, 00C00U, 0F300U, 00000U, 0F300U,
  392.     03000U, 0FC00U, 03000U, 03000U, 0CC00U, 00000U, 0CC00U, 0CC00U,
  393.     03000U, 03000U, 0FC00U, 03000U, 0CC00U, 0CC00U, 00000U, 0CC00U);
  394.  
  395. (*---------------------------------------------------------------------*)
  396.  
  397.   TYPE IntArray36 = ARRAY 36 OF INTEGER;
  398.   
  399.   CONST ZZData = IntArray36(
  400.     00000U,00000U,
  401.     00400U,007C0U,
  402.     00000U,007C0U,
  403.     00100U,00380U,
  404.     00000U,007E0U,
  405.     007C0U,01FF8U,
  406.     01FF0U,03FECU,
  407.     03FF8U,07FDEU,
  408.     03FF8U,07FBEU,
  409.     07FFCU,0FF7FU,
  410.     07EFCU,0FFFFU,
  411.     07FFCU,0FFFFU,
  412.     03FF8U,07FFEU,
  413.     03FF8U,07FFEU,
  414.     01FF0U,03FFCU,
  415.     007C0U,01FF8U,
  416.     00000U,007E0U,
  417.     00000U,00000U);
  418.  
  419. (*------------------------------------------------------------------------*)
  420.  
  421.   CONST
  422.     kmeIconWidth = 202;
  423.     kmeIconHeight = 19;
  424.  
  425.   TYPE IntArray494 = ARRAY 2,247 OF INTEGER;
  426.  
  427.   CONST KmeIconData = IntArray494(
  428.     (* [0] *)
  429.     00000U,00000U,00000U,00000U,00000U,00000U,00000U,00000U,00000U,00000U,00000U,00000U,00000U,
  430.     07FFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFC0U,
  431.     07FFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFC0U,
  432.     07FFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFC0U,
  433.     07F9EU,0418FU,081FFU,08007U,0FFFFU,0F9E7U,0FFFFU,0FFFFU,0FFFFU,0F03FU,0CCF9U,0FFFFU,0FFC0U,
  434.     07F9CU,0C427U,03CFFU,0F9E7U,0FFFFU,0F9CFU,0FFFFU,0FFFFU,0FFFFU,0E79FU,0CFF9U,0FFFFU,0FFC0U,
  435.     07F33U,09CE4U,0FFFFU,0F3C0U,0787FU,0F33EU,01CF0U,033C0U,081FFU,09FF0U,019E0U,07060U,03FC0U,
  436.     07F27U,09CE4U,0FFFFU,0F3C7U,0333FU,0F27CU,0CE70U,0019EU,01CFFU,09FE7U,019F3U,0E723U,09FC0U,
  437.     07E0FU,039C8U,03C03U,0E79FU,00CFFU,0E0F3U,03E61U,0987CU,03CFFU,0079FU,033E7U,09F0FU,0FFC0U,
  438.     07E27U,039C9U,0FFFFU,0E79FU,009FFU,0E272U,07F21U,0987CU,03CFFU,03F9FU,033E7U,09F0FU,0FFC0U,
  439.     07CE6U,07393U,0FFFFU,0CF3EU,0073FU,0CE61U,0CF03U,030F8U,079FEU,07F3EU,067CFU,03E1FU,0FFC0U,
  440.     07CF2U,07399U,0E7FFU,0CF3EU,04E7FU,0CF33U,09F83U,03270U,073FFU,03C9CU,0E7CFU,09C9FU,0FFC0U,
  441.     079F0U,0E738U,01FFFU,09E7CU,0C1FFU,09F30U,06786U,06600U,00FFFU,00383U,0CF9FU,0833FU,0FFC0U,
  442.     07FFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0F33FU,0FFFCU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFC0U,
  443.     07FFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0F0FFU,0FFFDU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFC0U,
  444.     07FFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFC0U,
  445.     07FFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFC0U,
  446.     07FFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFC0U,
  447.     07FFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFC0U,
  448.     (* [1] *)
  449.     0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFC0U,
  450.     0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FF80U,
  451.     0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FF80U,
  452.     0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FF80U,
  453.     0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FF80U,
  454.     0FFEFU,03BDFU,0C3FFU,0C61BU,0FFFFU,0FEF3U,0FFFFU,0FFFFU,0FFFFU,0F87FU,0F67EU,0FFFFU,0FF80U,
  455.     0FFCEU,0631BU,09E7FU,0FCFFU,0FFFFU,0FCE7U,0FFFFU,0FFFFU,0FFFFU,0F3CFU,0E7FFU,0FFFFU,0FF80U,
  456.     0FFD9U,0EF7BU,07FFFU,0FDF8U,0FCFFU,0FD9FU,03FFFU,0FFE1U,0E3FFU,0EFF8U,0EEFCU,038FCU,07F80U,
  457.     0FFF3U,0CE77U,0FFFFU,0F9E3U,0FB9FU,0FF3EU,0E7BEU,067CFU,0CF7FU,0FFF3U,0CCF9U,0F3F1U,0CF80U,
  458.     0FFDFU,0DEF6U,01E01U,0FBEFU,0F67FU,0FDFDU,09FFEU,0EFBFU,0DF7FU,0C3EFU,0DDFBU,0EFF7U,0FF80U,
  459.     0FF1BU,09CECU,0FFFFU,0F3CFU,0FCFFU,0F1BFU,03FFCU,0CF3FU,09E7FU,09FCFU,099F3U,0CFE7U,0FF80U,
  460.     0FF7FU,0BDEFU,0FFFFU,0F7DFU,0B39FU,0F7FCU,0E7FDU,0DDFFU,0BCFFU,0FFFFU,03BF7U,0FF6FU,0FF80U,
  461.     0FE7FU,039CFU,0F3FFU,0E79FU,03F3FU,0E7DFU,0DFF9U,099FFU,0F9FFU,0FE7EU,073E7U,0FECFU,0FF80U,
  462.     0FCF8U,0739CU,00FFFU,0CF3EU,060FFU,0CF98U,03FC3U,03303U,007FFU,081C1U,0E7CFU,0C19FU,0FF80U,
  463.     0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FF9FU,0FFFEU,07FFFU,0FFFFU,0FFFFU,0FFFFU,0FF80U,
  464.     0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0F87FU,0FFFEU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FF80U,
  465.     0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FF80U,
  466.     0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FF80U,
  467.     08000U,00000U,00000U,00000U,00000U,00000U,00000U,00000U,00000U,00000U,00000U,00000U,00000U);
  468.  
  469. (*------------------------------------------------------------------------*)
  470.  
  471.   CONST
  472.     kmePicWidth  = 190;
  473.     kmePicHeight =  11;
  474.  
  475.   TYPE IntArray132 = ARRAY 132 OF INTEGER;
  476.  
  477.   CONST KmePicData = IntArray132(
  478.     0F3C8U,031F0U,03FF0U,000FFU,0FFFFU,03CFFU,0FFFFU,0FFFFU,0FFFEU,007F9U,09F3FU,0FFFFU,
  479.     0F398U,084E7U,09FFFU,03CFFU,0FFFFU,039FFU,0FFFFU,0FFFFU,0FFFCU,0F3F9U,0FF3FU,0FFFFU,
  480.     0E673U,09C9FU,0FFFEU,0780FU,00FFEU,067C3U,09E06U,07810U,03FF3U,0FE03U,03C0EU,00C07U,
  481.     0E4F3U,09C9FU,0FFFEU,078E6U,067FEU,04F99U,0CE00U,033C3U,09FF3U,0FCE3U,03E7CU,0E473U,
  482.     0C1E7U,03907U,0807CU,0F3E1U,09FFCU,01E67U,0CC33U,00F87U,09FE0U,0F3E6U,07CF3U,0E1FFU,
  483.     0C4E7U,0393FU,0FFFCU,0F3E1U,03FFCU,04E4FU,0E433U,00F87U,09FE7U,0F3E6U,07CF3U,0E1FFU,
  484.     09CCEU,0727FU,0FFF9U,0E7C0U,0E7F9U,0CC39U,0E066U,01F0FU,03FCFU,0E7CCU,0F9E7U,0C3FFU,
  485.     09E4EU,0733CU,0FFF9U,0E7C9U,0CFF9U,0E673U,0F066U,04E0EU,07FE7U,0939CU,0F9F3U,093FFU,
  486.     03E1CU,0E703U,0FFF3U,0CF98U,03FF3U,0E60CU,0F0CCU,0C001U,0FFE0U,07079U,0F3F0U,067FFU,
  487.     0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFEU,067FFU,0FF9FU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,
  488.     0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU,0FFFEU,01FFFU,0FFBFU,0FFFFU,0FFFFU,0FFFFU,0FFFFU);
  489.  
  490. (*------------------------------------------------------------------------*)
  491.  
  492.   PROCEDURE Busy(win: I.WindowPtr);
  493.   BEGIN
  494.     I.SetPointer(win,zz^,16,16,-6,0);
  495.   END Busy;
  496.  
  497. (*------------------------------------------------------------------------*)
  498.  
  499.   PROCEDURE Iconify (VAR x,y: INTEGER; VAR Image: I.Image);
  500.     VAR
  501.       nw           : I.NewWindow;
  502.       win          : I.WindowPtr;
  503.       msg          : I.IntuiMessagePtr;
  504.       gad          : I.Gadget;
  505.       firstClick,endFlag : BOOLEAN;
  506.       lastSec,lastMic    : LONGINT;
  507.       second, micro      : LONGINT;
  508.   BEGIN
  509.     gad := I.Gadget(NIL,0,0,0,0,{I.gRelWidth,I.gRelHeight}+I.gadgHNone,
  510.            {I.gadgImmediate},I.wDragging,NIL,NIL,NIL,LONGSET{},NIL,0,NIL);
  511.     nw  := I.NewWindow(0,0,0,0,0,1,LONGSET{I.gadgetDown},
  512.            LONGSET{I.noCareRefresh,I.borderless},NIL,
  513.            NIL,NIL,NIL,NIL,0,0,-1,-1,{I.wbenchScreen});
  514.     nw.leftEdge:= x; nw.topEdge := y;
  515.     nw.width   := Image.width; nw.height  := Image.height;
  516.     nw.firstGadget := sys.ADR(gad);
  517.     win := I.OpenWindow(nw);
  518.     IF win#NIL THEN
  519.       I.DrawImage(win.rPort,Image,0,0);
  520.       endFlag := FALSE; firstClick := TRUE;
  521.       REPEAT
  522.         e.WaitPort(win.userPort);
  523.         msg := e.GetMsg(win.userPort) ;
  524.         WHILE msg # NIL DO
  525.          second := msg.time.secs;
  526.          micro  := msg.time.micro;
  527.          e.ReplyMsg(msg) ;
  528.          IF NOT firstClick THEN
  529.            endFlag:=I.DoubleClick(lastSec,lastMic,second,micro);
  530.          ELSE
  531.            firstClick:=FALSE;
  532.          END;
  533.          msg := e.GetMsg(win.userPort) ;
  534.          lastSec:=second; lastMic:=micro;
  535.         END;
  536.       UNTIL endFlag;
  537.       x := win.leftEdge; y := win.topEdge;
  538.       I.CloseWindow(win);
  539.     END;
  540.   END Iconify;
  541.  
  542. (*------------------------------------------------------------------------*)
  543.  
  544.   PROCEDURE GetIMsg (win:     I.WindowPtr;
  545.                      VAR mes: I.IntuiMessage;
  546.                      wait:    BOOLEAN);
  547.     VAR msg : I.IntuiMessagePtr;
  548.         waited: BOOLEAN;
  549.   BEGIN
  550.     waited := NOT wait;
  551.     msg := e.GetMsg(win.userPort);
  552.     IF (msg = NIL) & wait THEN
  553.       e.WaitPort(win.userPort);
  554.       msg := e.GetMsg(win.userPort);
  555.       waited := TRUE;
  556.     END;
  557.     IF msg # NIL THEN
  558.       LOOP
  559.         mes := msg^;
  560.         e.ReplyMsg(msg);
  561.         IF (mes.class * LONGSET{I.gadgetUp,I.closeWindow,I.rawKey}) = LONGSET{} THEN EXIT END;
  562.         msg := e.GetMsg(win.userPort);
  563.         IF msg = NIL THEN
  564.           IF NOT waited THEN mes.class := LONGSET{} END;
  565.           EXIT;
  566.         END;
  567.       END;
  568.     ELSE
  569.       mes.class := LONGSET{}
  570.     END;
  571.   END GetIMsg;
  572.  
  573. (*------------------------------------------------------------------------*)
  574.  
  575.   PROCEDURE FindGadget(id: INTEGER): I.GadgetPtr;
  576.     VAR i: INTEGER;
  577.   BEGIN
  578.     i := 0;
  579.     WHILE i < gadCnt DO
  580.       IF gad[i].gadgetID = id THEN RETURN sys.ADR(gad[i]) END;
  581.       INC(i);
  582.     END;
  583.     HALT(0);
  584.   END FindGadget;
  585.  
  586. (*---------------------------------------------------------------------*)
  587.  
  588.   PROCEDURE PutImage(rp               : g.RastPortPtr;
  589.                      x,y,width,height : INTEGER;
  590.                      data             : e.APTR;
  591.                      mode             : INTEGER);
  592.     VAR
  593.       img: I.Image;
  594.       dat: POINTER TO BYTE;
  595.  
  596.   BEGIN
  597.     dat := data;
  598.     e.CopyMem(dat^,chipBuf^,SIZE(chipBuf^));
  599.     img.leftEdge := 6;
  600.     img.topEdge := 1;
  601.     img.width := width;
  602.     img.height := height;
  603.     IF mode < 2 THEN
  604.       img.depth := 1;
  605.     ELSE
  606.       img.depth := 2;
  607.     END;
  608.     img.imageData := chipBuf;
  609.     CASE mode OF
  610.     | 0:
  611.       img.planePick := SHORTSET{0};
  612.       img.planeOnOff := SHORTSET{};
  613.     | 1:
  614.       img.planePick := SHORTSET{1};
  615.       img.planeOnOff := SHORTSET{0};
  616.     ELSE
  617.       img.planePick := SHORTSET{0,1};
  618.       img.planeOnOff := SHORTSET{0};
  619.     END;
  620.     img.nextImage := NIL;
  621.     I.DrawImage(rp,img,x,y);
  622.   END PutImage;
  623.  
  624. (*---------------------------------------------------------------------*)
  625.  
  626.   PROCEDURE AsciiToRaw(VAR s1,s2: String);
  627.  
  628.     VAR i,j,l,n,z : INTEGER;
  629.         state     : INTEGER;
  630.         ch        : CHAR;
  631.  
  632.     PROCEDURE AddChar(ch: CHAR);
  633.     BEGIN
  634.       IF j < strLen THEN
  635.         s2[j] := ch;
  636.         INC(j);
  637.       END;
  638.     END AddChar;
  639.  
  640.     PROCEDURE Hex2Dez(ch: CHAR; VAR z: INTEGER): BOOLEAN;
  641.     BEGIN
  642.       IF (ch >= "0") & (ch <= "9") THEN
  643.         z := ORD(ch) - ORD("0");
  644.         RETURN TRUE;
  645.       END;
  646.       ch := CAP(ch);
  647.       IF (ch >= "A") & (ch <= "F") THEN
  648.         z := 10 + (ORD(ch) - ORD("A"));
  649.         RETURN TRUE;
  650.       END;
  651.       RETURN FALSE;
  652.     END Hex2Dez;
  653.  
  654.   BEGIN  (* AsciiToRaw *)
  655.     state := 0;
  656.     l := str.Length(s1);
  657.     j := 0;
  658.     i := 0; WHILE i <= l DO
  659.       IF i < l THEN
  660.         ch := s1[i]
  661.       ELSE
  662.         ch := 0X
  663.       END;
  664.       CASE state OF
  665.       | 0:
  666.         IF ch = "\\" THEN
  667.           state := 1;
  668.         ELSE
  669.           AddChar(ch);
  670.         END;
  671.       | 1:
  672.         CASE CAP(ch) OF
  673.         | "N": AddChar(0AX); state := 0
  674.         | "R": AddChar(0DX); state := 0
  675.         | "E": AddChar(1BX); state := 0
  676.         | "[": AddChar(9BX); state := 0
  677.         | "O": AddChar(00X); state := 0
  678.         | "T": AddChar(09X); state := 0
  679.         | "B": AddChar(08X); state := 0
  680.         | "F": AddChar(0CX); state := 0
  681.         | "X": state := 2; n := 0;
  682.         ELSE
  683.           AddChar(ch);
  684.           state := 0;
  685.         END;
  686.       | 2,3:
  687.         IF Hex2Dez(ch,z) THEN
  688.           n := n * 16 + z;
  689.           INC(state);
  690.         ELSE
  691.           AddChar(CHR(n));
  692.           state := 0;
  693.           DEC(i);
  694.         END;
  695.       | 4:
  696.         state := 0;
  697.         AddChar(CHR(n));
  698.         DEC(i);
  699.       END;
  700.     INC(i) END;
  701.     AddChar(0X);
  702.     s2[strLen-1] := 0X
  703.   END AsciiToRaw;
  704.  
  705. (*---------------------------------------------------------------------*)
  706.  
  707.   PROCEDURE RawToAscii(VAR s1,s2: String; hex: BOOLEAN);
  708.  
  709.     CONST
  710.       hexStr = "0123456789ABCDEF";
  711.  
  712.     VAR
  713.       i,j,l   : INTEGER;
  714.       ch      : CHAR;
  715.       ctrl    : BOOLEAN;
  716.  
  717.     PROCEDURE AddChar(ch: CHAR);
  718.     BEGIN
  719.       IF j < strLen THEN
  720.         s2[j] := ch;
  721.         INC(j);
  722.       END;
  723.     END AddChar;
  724.  
  725.     PROCEDURE AddHex(ch: CHAR);
  726.     BEGIN
  727.       AddChar(hexStr[ORD(ch) DIV 16]);
  728.       AddChar(hexStr[ORD(ch) MOD 16]);
  729.     END AddHex;
  730.  
  731.   BEGIN
  732.     l := str.Length(s1);
  733.     j := 0;
  734.     i := 0; WHILE i < l DO
  735.       ch := s1[i];
  736.       ctrl := ((ORD(ch) MOD 128) < 32) OR hex;
  737.       IF ctrl THEN
  738.         AddChar("\\");
  739.         IF hex THEN
  740.           AddChar("x"); AddHex(ch);
  741.         ELSE
  742.           CASE ch OF
  743.           | 0AX: AddChar("n")
  744.           | 1BX: AddChar("e")
  745.           | 0DX: AddChar("r")
  746.           | 09X: AddChar("t")
  747.           | 9BX: AddChar("[")
  748.           | 08X: AddChar("b")
  749.           | 0CX: AddChar("f")
  750.           ELSE
  751.             AddChar("x"); AddHex(ch);
  752.           END;
  753.         END;
  754.       ELSE
  755.         AddChar(ch);
  756.         IF ch = "\\" THEN AddChar("\\") END;
  757.       END;
  758.     INC(i) END;
  759.     AddChar(0X);
  760.     s2[strLen-1] := 0X
  761.   END RawToAscii;
  762.  
  763. (*---------------------------------------------------------------------*)
  764.  
  765.   PROCEDURE DrawKey(key: Key; x,y: INTEGER);
  766.     VAR dummy,height,z : INTEGER;
  767.         buf: ARRAY 40 OF CHAR;
  768.         iev : ie.InputEventAdr;
  769.         num : LONGINT;
  770.   BEGIN
  771.     g.SetDrMd(rp,g.jam2);
  772.     height := keyHeight;
  773.     y := Y1+y-11;
  774.     INC(x,5);
  775.     IF (key.name="Entr") OR (key.name="Rtrn") THEN INC(height,height) END;
  776.     g.SetAPen(rp,1); g.SetBPen(rp,1);
  777.     g.RectFill(rp,x,y-1,x+key.width-1,y+height-1);
  778.     IF key.type = white THEN
  779.       g.SetAPen(rp,1); g.SetBPen(rp,2);
  780.     ELSE
  781.       g.SetAPen(rp,1); g.SetBPen(rp,3);
  782.     END;
  783.     g.RectFill(rp,x+1,y,x+key.width-2,y+height-2);
  784.     IF key.type = white THEN
  785.       g.SetAPen(rp,2); g.SetBPen(rp,2);
  786.     ELSE
  787.       g.SetAPen(rp,3) ; g.SetBPen(rp,3);
  788.     END;
  789.     g.RectFill(rp,x+5,y,x+key.width-6,y+height-5);
  790.     IF key.name="x" THEN
  791.       iev.nextEvent := NIL;
  792.       iev.class     := ie.rawkey;
  793.       iev.subClass  := ie.null;
  794.       iev.code      := key.code;
  795.       iev.qualifier := {};
  796.       iev.addr := NIL;
  797.       num := c.RawKeyConvert(sys.ADR(iev),buf,SIZE(buf),NIL);
  798.       IF    num=1 THEN key.name[0] := CAP(buf[0])
  799.       ELSIF num>1 THEN key.name[0] := buf[0]
  800.                   ELSE IF (key.code#43)&(key.code#48) THEN
  801.                          key.name := "´"
  802.                        ELSE
  803.                          key.name := " "
  804.                        END;
  805.       END;
  806.       g.SetAPen(rp,1); g.SetDrMd(rp,g.jam1); g.Move(rp,x+6,y+7);
  807.       g.Text(rp,key.name,1);
  808.     ELSE
  809.       IF    key.name="Alt"  THEN PutImage(rp,x,y,14,5,sys.ADR(Pics16Data[55]),1);
  810.       ELSIF key.name="LAmi" THEN PutImage(rp,x,y,9,5,sys.ADR(Pics16Data[80]),1);
  811.       ELSIF key.name="RAmi" THEN PutImage(rp,x,y,9,5,sys.ADR(Pics16Data[85]),1);
  812.       ELSIF key.name="Ctrl" THEN PutImage(rp,x,y,15,5,sys.ADR(Pics16Data[60]),1);
  813.       ELSIF key.name="Caps" THEN PutImage(rp,x,y-1,13,9,sys.ADR(Pics16Data[127]),1);
  814.       ELSIF key.name="Esc"  THEN PutImage(rp,x,y,13,5,sys.ADR(Pics16Data[70]),1);
  815.       ELSIF key.name="Help" THEN PutImage(rp,x,y,18,5,sys.ADR(Pics32Data[0]),1);
  816.       ELSIF key.name="Del"  THEN PutImage(rp,x,y,13,5,sys.ADR(Pics16Data[65]),1);
  817.       ELSIF key.name="Shft" THEN PutImage(rp,x,y,10,5,sys.ADR(Pics16Data[75]),1);
  818.       ELSIF key.name="Rtrn" THEN PutImage(rp,x+6,y+8,11,12,sys.ADR(Pics16Data[96]),1);
  819.       ELSIF key.name="Tab"  THEN PutImage(rp,x,y,12,6,sys.ADR(Pics16Data[90]),1);
  820.       ELSIF key.name="Left" THEN PutImage(rp,x,y,8,3,sys.ADR(ArrowData[0]),2);
  821.       ELSIF key.name="Rght" THEN PutImage(rp,x,y,8,3,sys.ADR(ArrowData[6]),2);
  822.       ELSIF key.name="Up"   THEN PutImage(rp,x,y,6,4,sys.ADR(ArrowData[12]),2);
  823.       ELSIF key.name="Down" THEN PutImage(rp,x,y,6,4,sys.ADR(ArrowData[20]),2);
  824.       ELSIF key.name="Bs"   THEN PutImage(rp,x,y,8,3,sys.ADR(ArrowData[3]),1);
  825.       ELSIF key.name="Entr" THEN PutImage(rp,x+2,y,4,19,sys.ADR(Pics16Data[108]),1);
  826.       ELSIF key.name[0]="f" THEN
  827.         PutImage(rp,x,y,5,5,sys.ADR(Pics16Data[0]),1);
  828.         z := ORD(key.name[1]) - ORD("0");
  829.         IF z = 0 THEN (* F10 *)
  830.           PutImage(rp,x+6,y,6,5,sys.ADR(Pics16Data[10]),1);
  831.           PutImage(rp,x+12,y,6,5,sys.ADR(Pics16Data[(z+1)*5]),1);
  832.         ELSE          (* F1 - F9 *)
  833.           PutImage(rp,x+6,y,6,5,sys.ADR(Pics16Data[(z+1)*5]),1);
  834.         END;
  835.       END;
  836.     END;
  837.     IF makeGads THEN
  838.       gad[gadCnt].leftEdge := x+5;
  839.       gad[gadCnt].topEdge := y;
  840.       gad[gadCnt].width := key.width-6-5+1;
  841.       gad[gadCnt].height := height-5+1;
  842.       gad[gadCnt].gadgetType := I.boolGadget;
  843.       gad[gadCnt].activation := {I.gadgImmediate,I.toggleSelect};
  844.       gad[gadCnt].gadgetID := idKey;
  845.       gad[gadCnt].flags := {};
  846.       gad[gadCnt].gadgetRender := NIL;
  847.       gad[gadCnt].selectRender := NIL;
  848.       gad[gadCnt].gadgetText := NIL;
  849.       gad[gadCnt].specialInfo := NIL;
  850.       gad[gadCnt].mutualExclude := LONGSET{};
  851.       gad[gadCnt].nextGadget := NIL;
  852.       gad[gadCnt].userData := key.code;
  853.     END;
  854.     dummy := I.AddGadget(win,gad[gadCnt],-1);
  855.     INC(gadCnt);
  856.   END DrawKey;
  857.  
  858. (*---------------------------------------------------------------------*)
  859.  
  860.   PROCEDURE DrawKeyRow(key: ARRAY OF Key; y: INTEGER); (* CopyArrays- *)
  861.     VAR i : INTEGER;
  862.         x : INTEGER;
  863.   BEGIN
  864.     x := 36;
  865.     i := 0; WHILE i < LEN(key) DO
  866.       IF key[i].type # nok THEN DrawKey(key[i],x,y) END;
  867.       INC(x,key[i].width);
  868.     INC(i) END;
  869.   END DrawKeyRow;
  870.  
  871. (*---------------------------------------------------------------------*)
  872.  
  873.   PROCEDURE DrawBorder (x,y,w,h: INTEGER);
  874.   BEGIN
  875.     g.SetDrMd(rp,g.jam1);
  876.     g.SetAPen(rp,2);
  877.     g.Move(rp,x+1,y+h-2); g.Draw(rp,x+1,y); g.Draw(rp,x+w-2,y);
  878.     g.Move(rp,x,y); g.Draw(rp,x,y+h-1);
  879.     g.SetAPen(rp,1);
  880.     g.Move(rp,x+1,y+h-1); g.Draw(rp,x+w-2,y+h-1); g.Draw(rp,x+w-2,y+1);
  881.     g.Move(rp,x+w-1,y); g.Draw(rp,x+w-1,y+h-1);
  882.   END DrawBorder;
  883.  
  884. (*---------------------------------------------------------------------*)
  885.  
  886.   PROCEDURE MakeGadget(x,y : INTEGER;
  887.                        txt : ARRAY OF CHAR;
  888.                        id  : INTEGER);       (* $CopyArrays- *)
  889.     VAR w,h : INTEGER;
  890.  
  891.   BEGIN
  892.     w := SHORT(LEN(txt))*8; h := 12;
  893.     IF txt[0] = 0X THEN
  894.       w := 46; h := 9;
  895.       PutImage(rp,x-3,y+1,7,5,sys.ADR(cycData),0);
  896.     ELSE
  897.       g.SetDrMd(rp,g.jam1); g.SetAPen(rp,1);
  898.       g.Move(rp,x+4,y+8); g.Text(rp,txt,LEN(txt)-1);
  899.     END;
  900.     DrawBorder(x,y,w,h);
  901.     IF makeGads THEN
  902.       gad[gadCnt].leftEdge := x;
  903.       gad[gadCnt].topEdge := y;
  904.       gad[gadCnt].width := w;
  905.       gad[gadCnt].height := h;
  906.       gad[gadCnt].gadgetType := I.boolGadget;
  907.       IF id >= 200 THEN
  908.         gad[gadCnt].activation := {I.gadgImmediate,I.toggleSelect};
  909.       ELSE
  910.         gad[gadCnt].activation := {I.relVerify};
  911.       END;
  912.       gad[gadCnt].gadgetID := id;
  913.       gad[gadCnt].flags := {};
  914.       gad[gadCnt].gadgetRender := NIL;
  915.       gad[gadCnt].selectRender := NIL;
  916.       gad[gadCnt].gadgetText := NIL;
  917.       gad[gadCnt].specialInfo := NIL;
  918.       gad[gadCnt].mutualExclude := LONGSET{};
  919.       gad[gadCnt].nextGadget := NIL;
  920.       gad[gadCnt].userData := NIL;
  921.     END;
  922.     dummy := I.AddGadget(win,gad[gadCnt],-1);
  923.     INC(gadCnt);
  924.   END MakeGadget;
  925.  
  926. (*---------------------------------------------------------------------*)
  927.  
  928.   PROCEDURE MakeStrGadget(x,y,w,id:INTEGER);
  929.   BEGIN
  930.     g.SetAPen(rp,1);
  931.     g.Move(rp,x,y+8);
  932.     g.Draw(rp,x+w,y+8);
  933.     IF makeGads THEN
  934.       gad[gadCnt].leftEdge := x;
  935.       gad[gadCnt].topEdge := y;
  936.       gad[gadCnt].width := w;
  937.       gad[gadCnt].height := 8;
  938.       gad[gadCnt].gadgetType := I.strGadget;
  939.       gad[gadCnt].activation := {I.relVerify,I.gadgImmediate};
  940.       gad[gadCnt].gadgetID := id;
  941.       gad[gadCnt].flags := {I.tabCycle};
  942.       gad[gadCnt].gadgetRender := NIL;
  943.       gad[gadCnt].selectRender := NIL;
  944.       gad[gadCnt].gadgetText := NIL;
  945.       gad[gadCnt].specialInfo := sys.ADR(strInf[strCnt]);
  946.       gad[gadCnt].mutualExclude := LONGSET{};
  947.       gad[gadCnt].nextGadget := NIL;
  948.       gad[gadCnt].userData := NIL;
  949.       buffer[strCnt,0] := 0X;
  950.       strInf[strCnt].buffer := sys.ADR(buffer[strCnt]);
  951.       strInf[strCnt].undoBuffer := sys.ADR(undobf[strCnt]);
  952.       strInf[strCnt].maxChars := strLen;
  953.       strInf[strCnt].extension := NIL;
  954.     END;
  955.     dummy := I.AddGadget(win,gad[gadCnt],-1);
  956.     INC(gadCnt);
  957.     INC(strCnt);
  958.   END MakeStrGadget;
  959.  
  960. (*---------------------------------------------------------------------*)
  961.  
  962.   PROCEDURE NumQual(type: SHORTSET): INTEGER;
  963.     VAR n: INTEGER;
  964.         deskr: BOOLEAN;
  965.   BEGIN
  966.     n := 1;
  967.     IF km.alt     IN type THEN INC(n,n) END;
  968.     IF km.shift   IN type THEN INC(n,n) END;
  969.     IF km.control IN type THEN INC(n,n) END;
  970.     IF km.nop IN type THEN n := 0 END;
  971.     deskr := (km.string IN type) OR (km.dead IN type);
  972.     IF ~deskr & (n > 4) THEN n := 4 END;
  973.     RETURN n
  974.   END NumQual;
  975.  
  976. (*---------------------------------------------------------------------*)
  977.  
  978.   PROCEDURE SetModGads;
  979.     VAR i: INTEGER; gad: I.GadgetPtr;
  980.   BEGIN
  981.     i := 0; WHILE i < 8 DO
  982.       gad := FindGadget(idMod+i);
  983.       PutImage(rp,gad.leftEdge+6,gad.topEdge+1,30,5,sys.ADR(modData[sys.VAL(LONGINT,gad.userData)]),0);
  984.     INC(i) END;
  985.   END SetModGads;
  986.  
  987. (*---------------------------------------------------------------------*)
  988.  
  989.   PROCEDURE SetStrGads(type : SHORTSET);
  990.  
  991.     TYPE Tab = ARRAY 8,8 OF SHORTINT;
  992.  
  993.     CONST
  994.       tab  = Tab (0,0,0,0,0,0,0,0,
  995.                   0,1,0,0,0,0,0,0,
  996.                   0,2,0,0,0,0,0,0,
  997.                   0,1,2,3,0,0,0,0,
  998.                   0,4,0,0,0,0,0,0,
  999.                   0,1,4,5,0,0,0,0,
  1000.                   0,2,4,6,0,0,0,0,
  1001.                   0,1,2,3,4,5,6,7);
  1002.     VAR
  1003.       i,n : INTEGER;
  1004.       gad: I.GadgetPtr;
  1005.       qual : SHORTINT;
  1006.       qualStr : ARRAY 16 OF CHAR;
  1007.  
  1008.     PROCEDURE QualString(VAR qualStr : ARRAY OF CHAR; i: INTEGER);
  1009.       VAR l : INTEGER;
  1010.           q : SHORTSET;
  1011.     BEGIN
  1012.       qualStr := "";
  1013.       q := sys.VAL(SHORTSET,SHORT(i));
  1014.       IF km.shift   IN q THEN str.Append(qualStr,"SHFT+") END;
  1015.       IF km.alt     IN q THEN str.Append(qualStr,"ALT+") END;
  1016.       IF km.control IN q THEN str.Append(qualStr,"CTRL+") END;
  1017.       l := str.Length(qualStr);
  1018.       IF (l > 0) & (qualStr[l-1] = "+") THEN
  1019.         str.Delete(qualStr,l-1,1);
  1020.       END;
  1021.     END QualString;
  1022.  
  1023.   BEGIN
  1024.     g.SetDrMd(rp,g.jam2);
  1025.     g.SetAPen(rp,1); g.SetBPen(rp,0);
  1026.     n := NumQual(type);
  1027.     qual := sys.VAL(SHORTINT,type * SHORTSET{0,1,2});
  1028.     i := 0; WHILE i < 8 DO
  1029.       g.Move(rp,255+X2,i*10+112+Y1); g.Text(rp,"             ",13);
  1030.       gad := FindGadget(idStr+i);
  1031.       IF i < n THEN
  1032.         QualString(qualStr,tab[qual,i]);
  1033.         g.Move(rp,255+X2+(13-str.Length(qualStr))*8,i*10+112+Y1);
  1034.         g.Text(rp,qualStr,str.Length(qualStr));
  1035.         EXCL(gad.flags,I.gadgDisabled);
  1036.       ELSE
  1037.         INCL(gad.flags,I.gadgDisabled);
  1038.       END;
  1039.     INC(i) END;
  1040.     I.RefreshGList(FindGadget(idStr),win,NIL,8);
  1041.   END SetStrGads;
  1042.  
  1043. (*---------------------------------------------------------------------*)
  1044.  
  1045.   PROCEDURE ClearGadgets;
  1046.     VAR i: INTEGER;
  1047.         gadget:I.GadgetPtr;
  1048.   BEGIN
  1049.     I.RefreshGList(FindGadget(idShift),win,NIL,9);
  1050.     gadget := FindGadget(idShift);      EXCL(gadget.flags,I.selected);
  1051.     gadget := FindGadget(idAlt);        EXCL(gadget.flags,I.selected);
  1052.     gadget := FindGadget(idControl);    EXCL(gadget.flags,I.selected);
  1053.     gadget := FindGadget(idDownup);     EXCL(gadget.flags,I.selected);
  1054.     gadget := FindGadget(idString);     EXCL(gadget.flags,I.selected);
  1055.     gadget := FindGadget(idDead);       EXCL(gadget.flags,I.selected);
  1056.     gadget := FindGadget(idCapsable);   EXCL(gadget.flags,I.selected);
  1057.     gadget := FindGadget(idRepeatable); EXCL(gadget.flags,I.selected);
  1058.     gadget := FindGadget(idNop);        EXCL(gadget.flags,I.selected);
  1059.     IF lastKeyGad # NIL THEN
  1060.       INCL(lastKeyGad.flags,I.selected);
  1061.       I.RefreshGList(lastKeyGad,win,NIL,1);
  1062.       EXCL(lastKeyGad.flags,I.selected);
  1063.     END;
  1064.     i := 0; WHILE i < 8 DO
  1065.       buffer[i,0] := 0X;
  1066.       gadget := FindGadget(idMod+i);
  1067.       gadget.userData := 0;
  1068.     INC(i) END;
  1069.     SetStrGads(SHORTSET{});
  1070.     SetModGads;
  1071.     lastKeyGad := NIL;
  1072.     rawCode := -1;
  1073.     keyModified := FALSE;
  1074.   END ClearGadgets;
  1075.  
  1076. (*---------------------------------------------------------------------*)
  1077.  
  1078.   PROCEDURE SetType(type: SHORTSET);
  1079.  
  1080.     VAR gad : I.GadgetPtr;
  1081.  
  1082.     PROCEDURE Select(id,flag:INTEGER);
  1083.     BEGIN
  1084.       gad := FindGadget(id);
  1085.       IF flag IN type THEN
  1086.         INCL(gad.flags,I.selected)
  1087.       ELSE
  1088.         EXCL(gad.flags,I.selected)
  1089.       END;
  1090.     END Select;
  1091.  
  1092.   BEGIN
  1093.     I.RefreshGList(FindGadget(idShift),win,NIL,7);
  1094.     Select(idShift,km.shift);
  1095.     Select(idAlt,km.alt);
  1096.     Select(idControl,km.control);
  1097.     Select(idNop,km.nop);
  1098.     Select(idDead,km.dead);
  1099.     Select(idString,km.string);
  1100.     Select(idDownup,km.downup);
  1101.     I.RefreshGList(FindGadget(idShift),win,NIL,7);
  1102.   END SetType;
  1103.  
  1104. (*---------------------------------------------------------------------*)
  1105.  
  1106.   PROCEDURE GetType(VAR type: SHORTSET);
  1107.  
  1108.     PROCEDURE Select(id,flag:INTEGER);
  1109.       VAR gad : I.GadgetPtr;
  1110.     BEGIN
  1111.       gad := FindGadget(id);
  1112.       IF I.selected IN gad.flags THEN INCL(type,flag) END;
  1113.     END Select;
  1114.  
  1115.   BEGIN
  1116.     type := SHORTSET{};
  1117.     Select(idShift,km.shift);
  1118.     Select(idAlt,km.alt);
  1119.     Select(idControl,km.control);
  1120.     Select(idNop,km.nop);
  1121.     Select(idDead,km.dead);
  1122.     Select(idString,km.string);
  1123.     Select(idDownup,km.downup);
  1124.   END GetType;
  1125.  
  1126. (*---------------------------------------------------------------------*)
  1127.  
  1128.   PROCEDURE New(VAR adr: e.APTR; size : LONGINT);
  1129.   BEGIN
  1130.     IF size <= 0 THEN size := 1 END;
  1131.     LOOP
  1132.       ol.New(adr,size);
  1133.       IF adr # NIL THEN RETURN END;
  1134.       IF ~rq.Request(kmr,oom,rtry,cncl) THEN HALT(0) END;
  1135.     END;
  1136.   END New;
  1137.  
  1138. (*---------------------------------------------------------------------*)
  1139.  
  1140.   PROCEDURE IntToByte(i: INTEGER): BYTE;
  1141.   BEGIN
  1142.     rq.Assert((i >= 0) & (i < 256),"Range Error");
  1143.     (* $RangeChk- *)
  1144.     RETURN SHORT(i);
  1145.     (* $RangeChk= *)
  1146.   END IntToByte;
  1147.  
  1148. (*---------------------------------------------------------------------*)
  1149.  
  1150.   PROCEDURE GetKey(code : INTEGER);
  1151.  
  1152.     VAR
  1153.       strDeskr    : StrDeskrPtr;
  1154.       deadDeskr   : DeadDeskrPtr;
  1155.       deadType    : SHORTINT;
  1156.       charPtr     : e.STRPTR;
  1157.       i,len       : INTEGER;
  1158.       gadget      : I.GadgetPtr;
  1159.       type        : SHORTSET;
  1160.       keyInfo     : Str4;
  1161.       code64      : INTEGER;
  1162.       kmap        : KeyMapPtr;
  1163.  
  1164.   BEGIN
  1165.     IF (code < 0) OR (keyMap = NIL)  THEN RETURN END;
  1166.     code64 := code MOD 64;
  1167.     IF code >= 64 THEN
  1168.       kmap := sys.ADR(keyMap.hiKeyMapTypes)
  1169.     ELSE
  1170.       kmap := sys.ADR(keyMap.loKeyMapTypes)
  1171.     END;
  1172.  
  1173.     type := kmap.loKeyMapTypes^[code64];
  1174.     SetType(type);
  1175.  
  1176.     gadget := FindGadget(idCapsable);
  1177.     I.RefreshGList(gadget,win,NIL,2);
  1178.     IF (code64 MOD 8) IN kmap.loCapsable^[code64 DIV 8] THEN
  1179.       INCL(gadget.flags,I.selected)
  1180.     ELSE
  1181.       EXCL(gadget.flags,I.selected)
  1182.     END;
  1183.  
  1184.     gadget := FindGadget(idRepeatable);
  1185.     IF (code64 MOD 8) IN kmap.loRepeatable^[code64 DIV 8] THEN
  1186.       INCL(gadget.flags,I.selected)
  1187.     ELSE
  1188.       EXCL(gadget.flags,I.selected)
  1189.     END;
  1190.  
  1191.     gadget := FindGadget(idCapsable);
  1192.     I.RefreshGList(gadget,win,NIL,2);
  1193.  
  1194.     SetStrGads(type);
  1195.  
  1196.     i := 0; WHILE i < 8 DO
  1197.       gadget := FindGadget(idMod+i);
  1198.       gadget.userData := 0;
  1199.     INC(i) END;
  1200.  
  1201.     IF km.string IN type THEN
  1202.       strDeskr := sys.VAL(e.APTR,kmap.loKeyMap^[code64]);
  1203.       i := 0; WHILE i < NumQual(type) DO
  1204.         charPtr := sys.VAL(e.APTR,sys.VAL(LONGINT,strDeskr) + ORD(sys.VAL(BYTE,strDeskr^[i].offs)));
  1205.         len := ORD(sys.VAL(BYTE,strDeskr^[i].len));
  1206.         IF len >= strLen THEN len := strLen - 1 END;
  1207.         IF len > 0 THEN
  1208.           e.CopyMem(charPtr^,string,len);
  1209.         END;
  1210.         string[len] := 0X;
  1211.         RawToAscii(string,buffer[i],FALSE);
  1212.       INC(i) END;
  1213.       WHILE i < 8 DO
  1214.         buffer[i,0] := 0X;
  1215.       INC(i) END;
  1216.  
  1217.     ELSIF km.dead IN type THEN
  1218.  
  1219.       deadDeskr := sys.VAL(e.APTR,kmap.loKeyMap^[code64]);
  1220.  
  1221.       i := 0; WHILE i < NumQual(type) DO
  1222.         gadget := FindGadget(idMod+i);
  1223.         deadType := deadDeskr^[i].type;
  1224.         CASE deadType OF
  1225.         | 0:
  1226.           gadget.userData := 0;
  1227.           string[0] := CHR(deadDeskr^[i].val);
  1228.           string[1] := 0X;
  1229.           RawToAscii(string,buffer[i],FALSE);
  1230.  
  1231.         | 1: (* mod *)
  1232.           gadget.userData := 1;
  1233.           charPtr := sys.VAL(e.APTR,sys.VAL(LONGINT,deadDeskr) + ORD(sys.VAL(BYTE,deadDeskr^[i].val)));
  1234.           len := deadLen;
  1235.           IF len >= strLen THEN len := strLen - 1 END;
  1236.           IF len > 0 THEN
  1237.             e.CopyMem(charPtr^,string,len);
  1238.           END;
  1239.           string[len] := 0X;
  1240.           RawToAscii(string,buffer[i],FALSE);
  1241.  
  1242.         | 8: (* dead *)
  1243.           gadget.userData := 2;
  1244.           string[0] := CHR(deadDeskr^[i].val);
  1245.           string[1] := 0X;
  1246.           RawToAscii(string,buffer[i],TRUE);
  1247.  
  1248.         ELSE
  1249.         END;
  1250.       INC(i) END;
  1251.  
  1252.       WHILE i < 8 DO
  1253.         buffer[i,0] := 0X;
  1254.       INC(i) END;
  1255.  
  1256.     ELSE
  1257.  
  1258.       keyInfo := sys.VAL(Str4,kmap.loKeyMap^[code64]);
  1259.       i := 0; WHILE i < NumQual(type) DO
  1260.         string[0] := keyInfo[3-i];
  1261.         string[1] := 0X;
  1262.         RawToAscii(string,buffer[i],FALSE);
  1263.       INC(i) END;
  1264.       WHILE i < 8 DO
  1265.         buffer[i,0] := 0X;
  1266.       INC(i) END;
  1267.     END;
  1268.  
  1269.     SetModGads;
  1270.     I.RefreshGList(FindGadget(idStr),win,NIL,8);
  1271.  
  1272.   END GetKey;
  1273.  
  1274. (*---------------------------------------------------------------------*)
  1275.  
  1276.   PROCEDURE SetKey(code: INTEGER);
  1277.  
  1278.     VAR
  1279.       strDeskr    : StrDeskrPtr;
  1280.       deadDeskr   : DeadDeskrPtr;
  1281.       deadType    : SHORTINT;
  1282.       charPtr     : e.STRPTR;
  1283.       i,len       : INTEGER;
  1284.       size,offset : INTEGER;
  1285.       gadget      : I.GadgetPtr;
  1286.       type        : SHORTSET;
  1287.       keyInfo     : Str4;
  1288.       code64      : INTEGER;
  1289.       kmap        : KeyMapPtr;
  1290.  
  1291.   BEGIN
  1292.     IF (code < 0) OR (keyMap = NIL) THEN RETURN END;
  1293.  
  1294.     mapModified := TRUE;
  1295.  
  1296.     code64 := code MOD 64;
  1297.     IF code >= 64 THEN
  1298.       kmap := sys.ADR(keyMap.hiKeyMapTypes)
  1299.     ELSE
  1300.       kmap := sys.ADR(keyMap.loKeyMapTypes)
  1301.     END;
  1302.  
  1303.     GetType(type);
  1304.     kmap.loKeyMapTypes^[code64] := type;
  1305.  
  1306.     gadget := FindGadget(idCapsable);
  1307.     IF I.selected IN gadget.flags THEN
  1308.       INCL(kmap.loCapsable^[code64 DIV 8],code64 MOD 8)
  1309.     ELSE
  1310.       EXCL(kmap.loCapsable^[code64 DIV 8],code64 MOD 8)
  1311.     END;
  1312.  
  1313.     gadget := FindGadget(idRepeatable);
  1314.     IF I.selected IN gadget.flags THEN
  1315.       INCL(kmap.loRepeatable^[code64 DIV 8],code64 MOD 8)
  1316.     ELSE
  1317.       EXCL(kmap.loRepeatable^[code64 DIV 8],code64 MOD 8)
  1318.     END;
  1319.  
  1320.     IF km.string IN type THEN
  1321.  
  1322.       size := 0;
  1323.       i := 0; WHILE i < NumQual(type) DO
  1324.         INC(size,2);
  1325.         AsciiToRaw(buffer[i],string);
  1326.         INC(size,str.Length(string));
  1327.       INC(i) END;
  1328.  
  1329.       New(strDeskr,size);
  1330.  
  1331.       offset := NumQual(type) * 2;
  1332.       i := 0; WHILE i < NumQual(type) DO
  1333.         AsciiToRaw(buffer[i],string);
  1334.         charPtr := sys.VAL(e.APTR,sys.VAL(LONGINT,strDeskr) + offset);
  1335.         len := str.Length(string);
  1336.         IF len > 0 THEN
  1337.           e.CopyMem(string,charPtr^,len);
  1338.         END;
  1339.         strDeskr^[i].len := IntToByte(len);
  1340.         strDeskr^[i].offs := IntToByte(offset);
  1341.         INC(offset,str.Length(string));
  1342.       INC(i) END;
  1343.  
  1344.       kmap.loKeyMap^[code64] := sys.VAL(LONGINT,strDeskr);
  1345.  
  1346.     ELSIF km.dead IN type THEN
  1347.  
  1348.       size := 0;
  1349.       i := 0; WHILE i < NumQual(type) DO
  1350.         gadget := FindGadget(idMod + i);
  1351.         INC(size,2);
  1352.         IF sys.VAL(LONGINT,gadget.userData) = 1 THEN
  1353.           INC(size,deadLen)
  1354.         END;
  1355.       INC(i) END;
  1356.  
  1357.       New(deadDeskr,size);
  1358.  
  1359.       offset := NumQual(type) * 2;
  1360.  
  1361.       i := 0; WHILE i < NumQual(type) DO
  1362.  
  1363.         AsciiToRaw(buffer[i],string);
  1364.         gadget := FindGadget(idMod + i);
  1365.  
  1366.         CASE sys.VAL(LONGINT,gadget.userData) OF
  1367.         | 0:
  1368.           deadDeskr^[i].type := 0;
  1369.           deadDeskr^[i].val := sys.VAL(BYTE,string[0]);
  1370.  
  1371.         | 1:
  1372.           deadDeskr^[i].type := 1;
  1373.           deadDeskr^[i].val := IntToByte(offset);
  1374.           charPtr := sys.VAL(e.APTR,sys.VAL(LONGINT,deadDeskr) + offset);
  1375.           IF deadLen > 0 THEN
  1376.             e.CopyMem(string,charPtr^,deadLen);
  1377.           END;
  1378.           INC(offset,deadLen);
  1379.  
  1380.         | 2:
  1381.           deadDeskr^[i].type := 8;
  1382.           deadDeskr^[i].val := sys.VAL(BYTE,string[0]);
  1383.         END;
  1384.  
  1385.       INC(i) END;
  1386.  
  1387.       kmap.loKeyMap^[code64] := sys.VAL(LONGINT,deadDeskr);
  1388.  
  1389.     ELSE
  1390.  
  1391.       i := 0; WHILE i < NumQual(type) DO
  1392.         AsciiToRaw(buffer[i],string);
  1393.         keyInfo[3-i] := string[0];
  1394.       INC(i) END;
  1395.       WHILE i < 4 DO
  1396.         keyInfo[3-i] := 0X;
  1397.       INC(i) END;
  1398.       kmap.loKeyMap^[code64] := sys.VAL(LONGINT,keyInfo);
  1399.  
  1400.     END;
  1401.  
  1402.   END SetKey;
  1403.  
  1404. (*---------------------------------------------------------------------*)
  1405.  
  1406.   PROCEDURE PushRelo(offs: LONGINT);
  1407.   BEGIN
  1408.     reloTab[reloTabPtr] := offs;
  1409.     INC(reloTabPtr);
  1410.   END PushRelo;
  1411.  
  1412. (*---------------------------------------------------------------------*)
  1413.  
  1414.   PROCEDURE BaseName(VAR path,name: String);
  1415.     VAR i,j : INTEGER;
  1416.   BEGIN
  1417.     i := str.Length(path);
  1418.     WHILE (i > 0) & (path[i-1] # ":") & (path[i-1] # "/") DO
  1419.       DEC(i)
  1420.     END;
  1421.     j := 0;
  1422.     WHILE (i < strLen) & (j < strLen) & (path[i] # 0X) DO
  1423.       name[j] := path[i];
  1424.       INC(i); INC(j)
  1425.     END;
  1426.     IF j < strLen THEN name[j] := 0X END;
  1427.   END BaseName;
  1428.  
  1429. (*---------------------------------------------------------------------*)
  1430.  
  1431.   PROCEDURE SaveMap(keyMap: KeyMapPtr; VAR fileName: String);
  1432.  
  1433.     VAR
  1434.       i,code      : INTEGER;
  1435.       l,offset    : LONGINT;
  1436.       mapName     : String;
  1437.       kmap        : KeyMapPtr;
  1438.       strDeskr    : StrDeskrPtr;
  1439.       deadDeskr   : DeadDeskrPtr;
  1440.       file        : fs.File;
  1441.       ok          : BOOLEAN;
  1442.       node        : e.Node;
  1443.       size        : LONGINT;
  1444.       type        : SHORTSET;
  1445.       nameOffset  : LONGINT;
  1446.       hunkSize    : LONGINT;
  1447.       zero        : SHORTINT;
  1448.  
  1449.  
  1450.     PROCEDURE Write(dat: ARRAY OF BYTE); (* $CopyArrays- *)
  1451.     BEGIN
  1452.       ok := ok & fs.Write(file,dat);
  1453.     END Write;
  1454.  
  1455.     PROCEDURE WriteBlock(from: e.APTR; size: LONGINT);
  1456.     BEGIN
  1457.       IF ok THEN
  1458.         IF size > 0 THEN
  1459.           ok := fs.WriteBlock(file,from,size)
  1460.         END
  1461.       END
  1462.     END WriteBlock;
  1463.  
  1464.     PROCEDURE GetStrDeskrSize(strDeskr:StrDeskrPtr; type:SHORTSET): LONGINT;
  1465.       VAR j: INTEGER; size: LONGINT;
  1466.     BEGIN
  1467.       size := 0;
  1468.       j := 0; WHILE j < NumQual(type) DO
  1469.         INC(size,2);
  1470.         INC(size,strDeskr^[j].len);
  1471.       INC(j) END;
  1472.       RETURN size;
  1473.     END GetStrDeskrSize;
  1474.  
  1475.     PROCEDURE GetDeadDeskrSize(deadDeskr:DeadDeskrPtr;type:SHORTSET):LONGINT;
  1476.       VAR j: INTEGER; size: LONGINT;
  1477.     BEGIN
  1478.       size := 0;
  1479.       j := 0; WHILE j < NumQual(type) DO
  1480.         INC(size,2);
  1481.         IF deadDeskr^[j].type = 1 THEN INC(size,deadLen) END;
  1482.       INC(j) END;
  1483.       RETURN size;
  1484.     END GetDeadDeskrSize;
  1485.  
  1486.   BEGIN
  1487.     IF keyMap = NIL THEN RETURN END;
  1488.     ok := TRUE;
  1489.  
  1490.     BaseName(fileName,mapName);
  1491.     IF mapName[0] = 0X THEN
  1492.       IF rq.Request(kmr,csk,"",cncl) THEN END;
  1493.       RETURN;
  1494.     END;
  1495.  
  1496.     IF fs.Exists(fileName) THEN
  1497.       IF ~rq.Request(kmr,fae,ovw,cncl) THEN
  1498.         RETURN
  1499.       END;
  1500.     END;
  1501.  
  1502.     IF NOT fs.Open(file,fileName,TRUE) THEN
  1503.       IF rq.Request(kmr,csk,"",cncl) THEN END;
  1504.       RETURN;
  1505.     END;
  1506.  
  1507.     l := 03F3H;
  1508.     Write(l);
  1509.     l := 0;
  1510.     Write(l);
  1511.     l := 1;
  1512.     Write(l);
  1513.     l := 0;
  1514.     Write(l);
  1515.     Write(l);
  1516.     Write(l);
  1517.     l := 03E9H;
  1518.     Write(l);
  1519.     l := 0;
  1520.     Write(l);
  1521.  
  1522.     node := e.Node(NIL,NIL,0,0,NIL);
  1523.  
  1524.     Write(node);
  1525.     PushRelo(10);
  1526.  
  1527.     l := 76;  Write(l);
  1528.     l := 196; Write(l);
  1529.     l := 46;  Write(l);
  1530.     l := 61;  Write(l);
  1531.     l := 140; Write(l);
  1532.     l := 452; Write(l);
  1533.     l := 54;  Write(l);
  1534.     l := 69;  Write(l);
  1535.  
  1536.     PushRelo(14);
  1537.     PushRelo(18);
  1538.     PushRelo(22);
  1539.     PushRelo(26);
  1540.     PushRelo(30);
  1541.     PushRelo(34);
  1542.     PushRelo(38);
  1543.     PushRelo(42);
  1544.  
  1545.     WriteBlock(keyMap.loCapsable,8);
  1546.     WriteBlock(keyMap.hiCapsable,7);
  1547.     WriteBlock(keyMap.loRepeatable,8);
  1548.     WriteBlock(keyMap.hiRepeatable,7);
  1549.     Write(keyMap.loKeyMapTypes^);
  1550.     Write(keyMap.hiKeyMapTypes^);
  1551.  
  1552.     offset := 676;
  1553.     kmap := sys.ADR(keyMap.loKeyMapTypes);
  1554.     i := 0; WHILE i < 120 DO
  1555.       IF i = 64 THEN kmap := sys.ADR(keyMap.hiKeyMapTypes) END;
  1556.       code := i MOD 64;
  1557.       type := kmap.loKeyMapTypes[code];
  1558.       IF km.string IN type THEN
  1559.         PushRelo(i*4+196);
  1560.         strDeskr := sys.VAL(e.APTR,kmap.loKeyMap[code]);
  1561.         Write(offset);
  1562.         size := GetStrDeskrSize(strDeskr,type);
  1563.         INC(offset,size);
  1564.       ELSIF km.dead IN type THEN
  1565.         PushRelo(i*4+196);
  1566.         deadDeskr := sys.VAL(e.APTR,kmap.loKeyMap[code]);
  1567.         Write(offset);
  1568.         size := GetDeadDeskrSize(deadDeskr,type);
  1569.         INC(offset,size);
  1570.       ELSE
  1571.         Write(kmap.loKeyMap^[code]);
  1572.       END;
  1573.     INC(i) END;
  1574.  
  1575.     kmap := sys.ADR(keyMap.loKeyMapTypes);
  1576.     i := 0; WHILE i < 120 DO
  1577.       IF i = 64 THEN kmap := sys.ADR(keyMap.hiKeyMapTypes) END;
  1578.       code := i MOD 64;
  1579.       type := kmap.loKeyMapTypes^[code];
  1580.       IF km.string IN type THEN
  1581.         strDeskr := sys.VAL(e.APTR,kmap.loKeyMap^[code]);
  1582.         size := GetStrDeskrSize(strDeskr,type);
  1583.         WriteBlock(strDeskr,size);
  1584.       ELSIF km.dead IN type THEN
  1585.         deadDeskr := sys.VAL(e.APTR,kmap.loKeyMap^[code]);
  1586.         size := GetDeadDeskrSize(deadDeskr,type);
  1587.         WriteBlock(deadDeskr,size);
  1588.       END;
  1589.     INC(i) END;
  1590.  
  1591.     nameOffset := offset;
  1592.     size := str.Length(mapName);
  1593.     WriteBlock(sys.ADR(mapName),size);
  1594.     zero := 0;
  1595.     Write(zero);
  1596.     INC(offset,size+1);
  1597.     WHILE (offset MOD 4) # 0 DO INC(offset); Write(zero) END;
  1598.     hunkSize := offset DIV 4;
  1599.  
  1600.     l := 03ECH;       Write(l);
  1601.     l := reloTabPtr;  Write(l);
  1602.     l := 0;           Write(l);
  1603.     WHILE reloTabPtr > 0 DO
  1604.       DEC(reloTabPtr);
  1605.       l := reloTab[reloTabPtr];
  1606.       Write(l);
  1607.     END;
  1608.     l := 0;     Write(l);
  1609.     l := 03F2H; Write(l);
  1610.  
  1611.     ok := ok & fs.Move(file,5*4);
  1612.     Write(hunkSize);
  1613.     ok := ok & fs.Move(file,7*4);
  1614.     Write(hunkSize);
  1615.  
  1616.     ok := ok & fs.Move(file,8*4 + 10);
  1617.     Write(nameOffset);
  1618.  
  1619.     ok := fs.Close(file) & ok;
  1620.     IF NOT ok THEN
  1621.       IF rq.Request(kmr,wer,please,forget) THEN
  1622.         IF d.DeleteFile(fileName) THEN END;
  1623.       END;
  1624.     ELSE
  1625.       mapModified := FALSE;
  1626.     END;
  1627.   END SaveMap;
  1628.  
  1629. (*---------------------------------------------------------------------*)
  1630.  
  1631.   PROCEDURE GetDeadLen;
  1632.  
  1633.     VAR
  1634.       code,i,j   : INTEGER;
  1635.       kmap       : KeyMapPtr;
  1636.       deskr      : DeadDeskrPtr;
  1637.       type       : SHORTSET;
  1638.       val        : SHORTINT;
  1639.       offs       : INTEGER;
  1640.       nibble1    : INTEGER;
  1641.       nibble2    : INTEGER;
  1642.       maxNibble2 : INTEGER;
  1643.       maxFaktor  : INTEGER;
  1644.       faktor     : INTEGER;
  1645.  
  1646.   BEGIN
  1647.     maxNibble2 := 0;
  1648.     maxFaktor := 0;
  1649.     i := 0; WHILE i < 120 DO
  1650.       code := i MOD 64;
  1651.       IF i >= 64 THEN
  1652.         kmap := sys.ADR(keyMap.hiKeyMapTypes)
  1653.       ELSE
  1654.         kmap := sys.ADR(keyMap.loKeyMapTypes)
  1655.       END;
  1656.       type := kmap.loKeyMapTypes^[code];
  1657.       IF km.dead IN type THEN
  1658.         deskr := sys.VAL(e.APTR,kmap.loKeyMap^[code]);
  1659.         j := 0; WHILE j < NumQual(type) DO
  1660.           IF deskr^[j].type = 8 THEN
  1661.             val := deskr^[j].val;
  1662.             nibble1 := sys.LSH(val,-4);
  1663.             nibble2 := val MOD 16;
  1664.             IF nibble1 = 0 THEN
  1665.               IF nibble2 > maxNibble2 THEN maxNibble2 := nibble2 END;
  1666.             ELSE
  1667.               faktor := nibble1 * nibble2;
  1668.               IF faktor > maxFaktor THEN maxFaktor := faktor END;
  1669.             END;
  1670.           END;
  1671.         INC(j) END;
  1672.       END;
  1673.     INC(i) END;
  1674.     deadLen := maxFaktor + maxNibble2 + 1;
  1675.     IF deadLen <  1 THEN deadLen :=  1 END;
  1676.     IF deadLen > 32 THEN deadLen := 32 END;
  1677.   END GetDeadLen;
  1678.  
  1679. (*---------------------------------------------------------------------*)
  1680.  
  1681.   PROCEDURE SetUp(firstTime: BOOLEAN);
  1682.     VAR i: INTEGER; type: SHORTSET;
  1683.   BEGIN
  1684.     makeGads := firstTime;
  1685.     gadCnt := 0;
  1686.     strCnt := 0;
  1687.  
  1688.     win := I.OpenWindow(nw); rq.Assert(win # NIL,cow);
  1689.     rp := win.rPort;
  1690.     g.SetFont(rp,font);
  1691.     g.SetAPen(rp,2);
  1692.     g.RectFill(rp,25,Y1+2,615,104+Y1);
  1693.     I.DrawImage(rp,kmePic,400,Y1-11+20);
  1694.     g.SetAfPt(rp,sys.ADR(pat),1);
  1695.  
  1696.     DrawKeyRow(keyRow0,20);
  1697.     DrawKeyRow(keyRow1,25+keyHeight);
  1698.     DrawKeyRow(keyRow2,25+keyHeight*2);
  1699.     DrawKeyRow(keyRow3,25+keyHeight*3);
  1700.     DrawKeyRow(keyRow4,25+keyHeight*4);
  1701.     DrawKeyRow(keyRow5,25+keyHeight*5);
  1702.  
  1703.     MakeGadget(30+X1 ,108+Y1,"LOAD",idLoad);
  1704.     MakeGadget(116+X1,108+Y1,"SAVE",idSave);
  1705.     MakeGadget(202+X1,108+Y1,"ABOUT",idAbout);
  1706.     MakeGadget(30+X1 ,124+Y1,"SHIFT",idShift);
  1707.     MakeGadget(116+X1,124+Y1,"ALT",idAlt);
  1708.     MakeGadget(186+X1,124+Y1,"CONTROL",idControl);
  1709.     MakeGadget(30+X1 ,140+Y1,"DOWNUP",idDownup);
  1710.     MakeGadget(98+X1 ,140+Y1,"DEAD",idDead);
  1711.     MakeGadget(150+X1,140+Y1,"STRING",idString);
  1712.     MakeGadget(218+X1,140+Y1,"NOP",idNop);
  1713.     MakeGadget(30+X1 ,156+Y1,"CAPSABLE",idCapsable);
  1714.     MakeGadget(162+X1,156+Y1,"REPEATABLE",idRepeatable);
  1715.     MakeGadget(30+X1 ,172+Y1,"QUIT",idQuit);
  1716.     MakeGadget(108+X1,172+Y1,"ICONIFY",idIconify);
  1717.     MakeGadget(210+X1,172+Y1,"UNDO",idUndo);
  1718.  
  1719.     i := 0; WHILE i < 8 DO
  1720.       MakeStrGadget(370+X2,106+Y1+i*10,192,idStr+i);
  1721.     INC(i) END;
  1722.  
  1723.     i := 0; WHILE i < 8 DO
  1724.       MakeGadget(574,106+Y1+i*10,"",idMod+i);
  1725.     INC(i) END;
  1726.  
  1727.     I.RefreshGList(sys.ADR(gad[0]),win,NIL,gadCnt);
  1728.  
  1729.     IF firstTime THEN
  1730.       type := SHORTSET{}
  1731.     ELSE
  1732.       GetType(type);
  1733.     END;
  1734.  
  1735.     SetStrGads(type);
  1736.     SetModGads;
  1737.  
  1738.   END SetUp;
  1739.  
  1740. (*---------------------------------------------------------------------*)
  1741.  
  1742.   PROCEDURE Quit;
  1743.   BEGIN
  1744.     IF keyModified THEN
  1745.       SetKey(rawCode);
  1746.       keyModified := FALSE;
  1747.     END;
  1748.     IF ~mapModified OR rq.Request(kmr,quit,please,forget) THEN
  1749.       HALT(0)
  1750.     END;
  1751.   END Quit;
  1752.  
  1753. (*---------------------------------------------------------------------*)
  1754.  
  1755.  
  1756. BEGIN
  1757.   IF ver[0]=0X THEN END;
  1758.  
  1759.   win := NIL; scr := NIL; font := NIL; seg := NIL; con := FALSE;
  1760.   lastKeyGad := NIL; keyModified := FALSE;
  1761.   rawCode := -1; reloTabPtr := 0; mapModified := FALSE;
  1762.   iconX := 350; iconY := 40;
  1763.   fileName := "DEVS:keymaps/";
  1764.  
  1765.   INCL(ol.MemReqs,e.chip);
  1766.   NEW(chipBuf);
  1767.   NEW(zz);
  1768.   NEW(kmeIconData);
  1769.   NEW(kmePicData);
  1770.   EXCL(ol.MemReqs,e.chip);
  1771.  
  1772.   rq.Assert((chipBuf # NIL) & (zz # NIL) &
  1773.             (kmeIconData # NIL) & (kmePicData # NIL),ooc);
  1774.  
  1775.   e.CopyMem(ZZData,zz^,SIZE(zz^));
  1776.   e.CopyMem(KmeIconData,kmeIconData^,SIZE(kmeIconData^));
  1777.   e.CopyMem(KmePicData,kmePicData^,SIZE(kmePicData^));
  1778.  
  1779.   kmeIcon := I.Image(0,0,kmeIconWidth,kmeIconHeight,2,NIL,SHORTSET{0,1},SHORTSET{},NIL);
  1780.   kmeIcon.imageData := kmeIconData;
  1781.  
  1782.   kmePic := I.Image(0,0,kmePicWidth,kmePicHeight,1,NIL,SHORTSET{1},SHORTSET{},NIL);
  1783.   kmePic.imageData := kmePicData;
  1784.  
  1785.   i := 32; WHILE i <= 39 DO
  1786.     hiTypes[i] := SHORTSET{km.nop};
  1787.   INC(i) END;
  1788.  
  1789.   dfltKeyMap.loKeyMapTypes := sys.ADR(loTypes);
  1790.   dfltKeyMap.hiKeyMapTypes := sys.ADR(hiTypes);
  1791.   dfltKeyMap.loKeyMap := sys.ADR(loMap);
  1792.   dfltKeyMap.hiKeyMap := sys.ADR(hiMap);
  1793.   dfltKeyMap.loCapsable := sys.ADR(loCaps);
  1794.   dfltKeyMap.hiCapsable := sys.ADR(hiCaps);
  1795.   dfltKeyMap.loRepeatable := sys.ADR(loRepeat);
  1796.   dfltKeyMap.hiRepeatable := sys.ADR(hiRepeat);
  1797.   deadLen := 18;
  1798.  
  1799.   keyMap := sys.ADR(dfltKeyMap);
  1800.  
  1801.   attr := g.TextAttr(sys.ADR("topaz.font"),8,g.normalFont,SHORTSET{g.romFont});
  1802.   font := g.OpenFont(attr);
  1803.   IF font = NIL THEN HALT(0) END;
  1804.   pat[0] := 05555U;
  1805.   pat[1] := 0AAAAU;
  1806.  
  1807.   con := e.OpenDevice(c.consoleName,-1,sys.ADR(ioreq),LONGSET{}) = 0;
  1808.   IF NOT con THEN HALT(0) ELSE c.base := ioreq.device END;
  1809.  
  1810.   IF I.int.libNode.version>=36 THEN scr := I.LockPubScreen(NIL)
  1811.                                ELSE scr := I.OpenWorkBench() END;
  1812.   IF scr=NIL THEN HALT(0) END;
  1813.  
  1814.   nw := I.NewWindow(0,0,640,189,-1,-1,
  1815.                     LONGSET{I.closeWindow,I.gadgetUp,I.gadgetDown,I.rawKey},
  1816.                     LONGSET{I.windowDepth,I.windowDrag,I.windowClose,I.activate,I.rmbTrap},
  1817.                     NIL,NIL,sys.ADR("KME"),NIL,NIL,0,0,0,0,I.customScreen);
  1818.  
  1819.   Y1 := scr.wBorTop+scr.font.ySize+1;
  1820.   INC(nw.height,Y1);
  1821.  
  1822.   nw.screen := scr;
  1823.  
  1824.   IF nw.height > scr.height THEN
  1825.     DEC(Y1,nw.height-scr.height);
  1826.     nw.height := scr.height;
  1827.   END;
  1828.  
  1829.   SetUp(TRUE);
  1830.  
  1831.   LOOP
  1832.  
  1833.     GetIMsg(win,mes,TRUE);
  1834.  
  1835.     IF I.closeWindow IN mes.class THEN
  1836.       Quit;
  1837.  
  1838.     ELSIF I.rawKey IN mes.class THEN
  1839.       IF mes.code < 128 THEN
  1840.         gadget := FindGadget(idKey);
  1841.         WHILE (gadget # NIL)               &
  1842.               (gadget.gadgetID = idKey)    &
  1843.               (sys.VAL(LONGINT,gadget.userData) # mes.code)   DO
  1844.           gadget := gadget.nextGadget;
  1845.         END;
  1846.         IF sys.VAL(LONGINT,gadget.userData) = mes.code THEN
  1847.           IF lastKeyGad # NIL THEN
  1848.             INCL(lastKeyGad.flags,I.selected);
  1849.             I.RefreshGList(lastKeyGad,win,NIL,1);
  1850.             EXCL(lastKeyGad.flags,I.selected);
  1851.           END;
  1852.           INCL(gadget.flags,I.selected);
  1853.           I.RefreshGList(gadget,win,NIL,1);
  1854.           oldCode := rawCode;
  1855.           lastKeyGad := gadget;
  1856.           rawCode := SHORT(sys.VAL(LONGINT,gadget.userData));
  1857.           IF keyModified THEN
  1858.             SetKey(oldCode);
  1859.           END;
  1860.           GetKey(rawCode);
  1861.           keyModified := FALSE;
  1862.         END;
  1863.       END;
  1864.  
  1865.     ELSIF I.gadgetUp IN mes.class THEN
  1866.       clickedGad := mes.iAddress;
  1867.       gadID := clickedGad.gadgetID;
  1868.  
  1869.       CASE gadID OF
  1870.  
  1871.       | idQuit:
  1872.         Quit;
  1873.  
  1874.       | idLoad:
  1875.         IF keyModified THEN
  1876.           SetKey(rawCode);
  1877.           keyModified := FALSE;
  1878.         END;
  1879.         IF ~mapModified OR rq.Request(kmr,load,please,forget) THEN
  1880.           IF fr.FileReq("Load Keymap:",fileName) THEN
  1881.             Busy(win);
  1882.             newSeg := d.LoadSeg(fileName);
  1883.             I.ClearPointer(win);
  1884.             IF newSeg # NIL THEN
  1885.               IF seg # NIL THEN d.UnLoadSeg(seg) END;
  1886.               seg := newSeg;
  1887.               keyMap := sys.VAL(e.APTR,sys.VAL(LONGINT,seg)*4+4+SIZE(e.Node));
  1888.               GetDeadLen;
  1889.               ClearGadgets;
  1890.               mapModified := FALSE;
  1891.             ELSE
  1892.               IF rq.Request(kmr,clk,"",cncl) THEN END;
  1893.             END;
  1894.           END;
  1895.         END;
  1896.  
  1897.       | idSave:
  1898.         IF keyModified THEN
  1899.           SetKey(rawCode);
  1900.           keyModified := FALSE;
  1901.         END;
  1902.         IF fr.FileReqSave("Save Keymap:",fileName) THEN
  1903.           Busy(win);
  1904.           SaveMap(keyMap,fileName);
  1905.           I.ClearPointer(win);
  1906.         END;
  1907.  
  1908.       | idUndo:
  1909.         IF keyModified THEN
  1910.           GetKey(rawCode);
  1911.           keyModified := FALSE;
  1912.         END;
  1913.  
  1914.       | idMod .. idMod + 7:
  1915.         keyModified := TRUE;
  1916.         clickedGad.userData := sys.VAL(e.APTR,(sys.VAL(LONGINT,clickedGad.userData)+1) MOD 3);
  1917.         SetModGads;
  1918.  
  1919.       | idAbout:
  1920.         IF rq.Request(kme,cprt,"",ok) THEN END;
  1921.  
  1922.       | idStr..idStr+7:
  1923.         i := gadID - idStr;
  1924.         AsciiToRaw(buffer[i],string);
  1925.         gadget := FindGadget(idMod+i);
  1926.         RawToAscii(string,buffer[i],sys.VAL(LONGINT,gadget.userData) = 2);
  1927.         gadget := FindGadget(idStr+i);
  1928.         I.RefreshGList(gadget,win,NIL,1);
  1929.         keyModified := TRUE;
  1930.  
  1931.       | idIconify:
  1932.         nw.leftEdge := win.leftEdge;
  1933.         nw.topEdge  := win.topEdge;
  1934.         I.CloseWindow(win); win := NIL;
  1935.         Iconify(iconX,iconY,kmeIcon);
  1936.         SetUp(FALSE);
  1937.  
  1938.       ELSE
  1939.       END (*CASE*);
  1940.  
  1941.     ELSIF I.gadgetDown IN mes.class THEN
  1942.       clickedGad := mes.iAddress;
  1943.       gadID := clickedGad.gadgetID;
  1944.  
  1945.       CASE gadID OF
  1946.  
  1947.       | idStr..idStr+7:
  1948.         keyModified := TRUE;
  1949.  
  1950.       | idKey :
  1951.         IF lastKeyGad # NIL THEN
  1952.           INCL(lastKeyGad.flags,I.selected);
  1953.           I.RefreshGList(lastKeyGad,win,NIL,1);
  1954.           EXCL(lastKeyGad.flags,I.selected);
  1955.           INCL(clickedGad.flags,I.selected);
  1956.         END;
  1957.         oldCode := rawCode;
  1958.         lastKeyGad := clickedGad;
  1959.         rawCode := SHORT(sys.VAL(LONGINT,clickedGad.userData));
  1960.         IF keyModified THEN
  1961.           SetKey(oldCode);
  1962.         END;
  1963.         GetKey(rawCode);
  1964.         keyModified := FALSE;
  1965.  
  1966.       | idDead,idString:
  1967.         keyModified := TRUE;
  1968.         LOOP
  1969.           IF I.selected IN clickedGad.flags THEN
  1970.             gadget := FindGadget(idNop);
  1971.             IF I.selected IN gadget.flags THEN
  1972.               I.RefreshGList(clickedGad,win,NIL,1);
  1973.               EXCL(clickedGad.flags,I.selected);
  1974.               EXIT;
  1975.             ELSE
  1976.               IF gadID = idDead THEN
  1977.                 gadget := FindGadget(idString);
  1978.               ELSE
  1979.                 gadget := FindGadget(idDead);
  1980.               END;
  1981.               IF I.selected IN gadget.flags THEN
  1982.                 I.RefreshGList(gadget,win,NIL,1);
  1983.                 EXCL(gadget.flags,I.selected);
  1984.               END;
  1985.             END;
  1986.           END;
  1987.           GetType(type);
  1988.           SetStrGads(type);
  1989.           EXIT;
  1990.         END;
  1991.  
  1992.       | idAlt,idControl,idShift:
  1993.         keyModified := TRUE;
  1994.         LOOP
  1995.           IF I.selected IN clickedGad.flags THEN
  1996.             gadget := FindGadget(idNop);
  1997.             IF I.selected IN gadget.flags THEN
  1998.               I.RefreshGList(clickedGad,win,NIL,1);
  1999.               EXCL(clickedGad.flags,I.selected);
  2000.               EXIT;
  2001.             END;
  2002.           END;
  2003.           GetType(type);
  2004.           SetStrGads(type);
  2005.           EXIT
  2006.         END;
  2007.  
  2008.       | idCapsable,idRepeatable,idDownup:
  2009.         keyModified := TRUE;
  2010.         IF I.selected IN clickedGad.flags THEN
  2011.           gadget := FindGadget(idNop);
  2012.           IF I.selected IN gadget.flags THEN
  2013.             I.RefreshGList(clickedGad,win,NIL,1);
  2014.             EXCL(clickedGad.flags,I.selected);
  2015.           END;
  2016.         END;
  2017.  
  2018.       | idNop:
  2019.         keyModified := TRUE;
  2020.         IF I.selected IN clickedGad.flags THEN
  2021.           I.RefreshGList(FindGadget(idShift),win,NIL,6);
  2022.           I.RefreshGList(FindGadget(idCapsable),win,NIL,2);
  2023.           gadget := FindGadget(idShift);      EXCL(gadget.flags,I.selected);
  2024.           gadget := FindGadget(idAlt);        EXCL(gadget.flags,I.selected);
  2025.           gadget := FindGadget(idControl);    EXCL(gadget.flags,I.selected);
  2026.           gadget := FindGadget(idDownup);     EXCL(gadget.flags,I.selected);
  2027.           gadget := FindGadget(idString);     EXCL(gadget.flags,I.selected);
  2028.           gadget := FindGadget(idDead);       EXCL(gadget.flags,I.selected);
  2029.           gadget := FindGadget(idCapsable);   EXCL(gadget.flags,I.selected);
  2030.           gadget := FindGadget(idRepeatable); EXCL(gadget.flags,I.selected);
  2031.         END;
  2032.         GetType(type);
  2033.         SetStrGads(type);
  2034.  
  2035.       ELSE
  2036.       END (*CASE*);
  2037.  
  2038.     END (*IF*)
  2039.   END (*LOOP*)
  2040.  
  2041. CLOSE
  2042.  
  2043.   IF seg  # NIL THEN d.UnLoadSeg(seg) END;
  2044.   IF win  # NIL THEN I.CloseWindow(win) END;
  2045.   IF (I.int.libNode.version>=36)&(scr#NIL) THEN I.UnlockPubScreen(NIL,scr) END;
  2046.   IF font # NIL THEN g.CloseFont(font) END;
  2047.   IF con THEN e.CloseDevice(sys.ADR(ioreq)) END;
  2048.  
  2049. END KME.
  2050.  
  2051.  
  2052.  
  2053.